  <!DOCTYPE html>
  <html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="generator" content="pandoc" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <title>GTK 4 tutorial</title>
    <style>
      code{white-space: pre-wrap;}
      span.smallcaps{font-variant: small-caps;}
      span.underline{text-decoration: underline;}
      div.column{display: inline-block; vertical-align: top; width: 50%;}
      div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
      ul.task-list{list-style: none;}
      pre{overflow: visible;}
      pre > code.sourceCode { white-space: pre; position: relative; }
      pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
      pre > code.sourceCode > span:empty { height: 1.2em; }
      code.sourceCode > span { color: inherit; text-decoration: inherit; }
      div.sourceCode { margin: 1em 0; }
      pre.sourceCode { margin: 0; }
      @media screen {
      div.sourceCode { overflow: auto; }
      }
      @media print {
      pre > code.sourceCode { white-space: pre-wrap; }
      pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
      }
      pre.numberSource code
        { counter-reset: source-line 0; }
      pre.numberSource code > span
        { position: relative; left: -4em; counter-increment: source-line; }
      pre.numberSource code > span > a:first-child::after
        { content: counter(source-line);
          position: relative; left: -1em; text-align: right; vertical-align: baseline;
          border: none; display: inline-block;
          -webkit-touch-callout: none; -webkit-user-select: none;
          -khtml-user-select: none; -moz-user-select: none;
          -ms-user-select: none; user-select: none;
          padding: 0 4px; width: 4em;
          color: #aaaaaa;
        }
      pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
      div.sourceCode
        {   }
      @media screen {
      pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
      }
      code span.al { color: #ff0000; font-weight: bold; } /* Alert */
      code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
      code span.at { color: #7d9029; } /* Attribute */
      code span.bn { color: #40a070; } /* BaseN */
      code span.bu { } /* BuiltIn */
      code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
      code span.ch { color: #4070a0; } /* Char */
      code span.cn { color: #880000; } /* Constant */
      code span.co { color: #60a0b0; font-style: italic; } /* Comment */
      code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
      code span.do { color: #ba2121; font-style: italic; } /* Documentation */
      code span.dt { color: #902000; } /* DataType */
      code span.dv { color: #40a070; } /* DecVal */
      code span.er { color: #ff0000; font-weight: bold; } /* Error */
      code span.ex { } /* Extension */
      code span.fl { color: #40a070; } /* Float */
      code span.fu { color: #06287e; } /* Function */
      code span.im { } /* Import */
      code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
      code span.kw { color: #007020; font-weight: bold; } /* Keyword */
      code span.op { color: #666666; } /* Operator */
      code span.ot { color: #007020; } /* Other */
      code span.pp { color: #bc7a00; } /* Preprocessor */
      code span.sc { color: #4070a0; } /* SpecialChar */
      code span.ss { color: #bb6688; } /* SpecialString */
      code span.st { color: #4070a0; } /* String */
      code span.va { color: #19177c; } /* Variable */
      code span.vs { color: #4070a0; } /* VerbatimString */
      code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
      div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
      pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
      table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;}
      th {padding: 2px 6px; border: 1px solid; background-color: ghostwhite;}
      td {padding: 2px 6px; border: 1px solid;}
      img {display: block; margin-left: auto; margin-right: auto;}
      figcaption {text-align: center;}
    </style>
  </head>
  <body style="padding-top: 70px;">
    <div class="container">
    <nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-primary">
      <div class="container-fluid">
        <span class="navbar-brand">Gtk4 tutorial</span>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="navbar-nav me-auto mb-2 mb-lg-0">
            <li class="nav-item">
<a class="nav-link" href="index.html">Home</a>
</li>

            <li class="nav-item">
<a class="nav-link" href="sec2.html">Prev: section2</a>
</li>

            <li class="nav-item">
<a class="nav-link" href="sec4.html">Next: section4</a>
</li>

          </ul>
        </div>
      </div>
    </nav>
<h1 id="gtkapplication-and-gtkapplicationwindow">GtkApplication and
GtkApplicationWindow</h1>
<h2 id="gtkapplication">GtkApplication</h2>
<h3 id="gtkapplication-and-g_application_run">GtkApplication and
g_application_run</h3>
<p>People write programming code to make an application. What are
applications? Applications are software that runs using libraries, which
includes the OS, frameworks and so on. In GTK 4 programming, the
GtkApplication is a program (or executable) that runs using Gtk
libraries.</p>
<p>The basic way to write a GtkApplication is as follows.</p>
<ul>
<li>Create a GtkApplication instance.</li>
<li>Run the application.</li>
</ul>
<p>That’s all. Very simple. The following is the C code representing the
scenario above.</p>
<p>@@<span class="citation" data-cites="include">@include</span>
misc/pr1.c @@@</p>
<p>The first line says that this program includes the header files of
the Gtk libraries. The function <code>main</code> is a startup function
in C language. The variable <code>app</code> is defined as a pointer to
a GtkApplication instance. The function <code>gtk_application_new</code>
creates a GtkApplication instance and returns a pointer to the instance.
The GtkApplication instance is a C structure data in which the
information about the application is stored. The meaning of the
arguments will be explained later. The function
<code>g_application_run</code> runs an application that the instance
defined. (We often say that the function runs <code>app</code>.
Actually, <code>app</code> is not an application but a pointer to the
instance of the application. However, it is simple and short, and
probably no confusion occurs.)</p>
<p>Here I used the word <code>instance</code>. Instance, class and
object are terminologies in Object Oriented Programming. I use these
words in the same way. But, I will often use “object” instead of
“instance” in this tutorial. That means “object” and “instance” is the
same. Object is a bit ambiguous word. In a broad sense, object has wider
meaning than instance. So, readers should be careful of the contexts to
find the meaning of “object”. In many cases, object and instance are the
same.</p>
<p>The function <code>gtk_application_new</code> has two parameters.</p>
<ul>
<li><p>Application ID (com.github.ToshioCP.pr1). It is used to
distinguish applications by the system. The format is reverse-DNS. See
<a
href="https://developer.gnome.org/documentation/tutorials/application-id.html">GNOME
Developer Documentation – Application ID</a> for further
information.</p></li>
<li><p>Application flag (G_APPLICATION_DEFAULT_FLAGS). If the
application runs without any arguments, the flag is
G_APPLICATION_DEFAULT_FLAGS. Otherwise, you need other flags. See <a
href="https://docs.gtk.org/gio/flags.ApplicationFlags.html">GIO API
reference</a> for further information.</p></li>
</ul>
<p>To compile this, the following command needs to be run. The string
<code>pr1.c</code> is the filename of the C source code above.</p>
<p>Notice: If your GLib-2.0 version is older than 2.74, use
<code>G_APPLICATION_FLAGS_NONE</code> instead of
<code>G_APPLICATION_DEFAULT_FLAGS</code>. It is an old flag replaced by
<code>G_APPLICATION_DEFAULT_FLAGS</code> and deprecated since version
2.74. However, many distributions use GLib-2.0 version 2.72 or older,
for example, Ubuntu 22.04 LTS.</p>
<pre><code>$ gcc `pkg-config --cflags gtk4` pr1.c `pkg-config --libs gtk4`</code></pre>
<p>The C compiler gcc generates an executable file, <code>a.out</code>.
Let’s run it.</p>
<pre><code>$ ./a.out

(a.out:13533): GLib-GIO-WARNING **: 15:30:17.449: Your application does not implement
g_application_activate() and has no handlers connected to the &quot;activate&quot; signal.
It should do one of these.
$</code></pre>
<p>Oh, it just produces an error message. This error message means that
the GtkApplication object ran, without a doubt. Now, let’s think about
what this message means.</p>
<h3 id="signal">signal</h3>
<p>The message tells us that:</p>
<ol type="1">
<li>The application GtkApplication doesn’t implement
<code>g_application_activate()</code>,</li>
<li>It has no handlers connected to the “activate” signal, and</li>
<li>You will need to solve at least one of these.</li>
</ol>
<p>These two causes of the error are related to signals. So, I will
explain that to you first.</p>
<p>A signal is emitted when something happens. For example, a window is
created, a window is destroyed and so on. The signal “activate” is
emitted when the application is activated. (Activated is a bit different
from started, but you can think of them both as almost the same so far.)
If the signal is connected to a function, which is called a signal
handler or simply handler, then the function is invoked when the signal
emits.</p>
<p>The flow is like this:</p>
<ol type="1">
<li>Something happens.</li>
<li>If it’s related to a certain signal, then the signal is
emitted.</li>
<li>If the signal has been connected to a handler in advance, then the
handler is invoked.</li>
</ol>
<p>Signals are defined in objects. For example, the “activate” signal
belongs to the GApplication object, which is a parent object of
GtkApplication object.</p>
<p>The GApplication object is a child object of the GObject object.
GObject is the top object in the hierarchy of all the objects.</p>
<pre><code>GObject -- GApplication -- GtkApplication
&lt;---parent                      ---&gt;child</code></pre>
<p>A child object inherits signals, functions, properties and so on from
its parent object. So, GtkApplication also has the “activate”
signal.</p>
<p>Now we can solve the problem in <code>pr1.c</code>. We need to
connect the “activate” signal to a handler. We use a function
<code>g_signal_connect</code> which connects a signal to a handler.</p>
<p>@@<span class="citation" data-cites="include">@include</span>
misc/pr2.c @@@</p>
<p>First, we define the handler <code>app_activate</code> which simply
displays a message. The function <code>g_print</code> is defined in GLib
and it’s like a printf in the C standard library. In the function
<code>main</code>, we add <code>g_signal_connect</code> before
<code>g_application_run</code>. The function
<code>g_signal_connect</code> has four arguments.</p>
<ol type="1">
<li>An instance to which the signal belongs.</li>
<li>The name of the signal.</li>
<li>A handler function (also called callback), which needs to be casted
by <code>G_CALLBACK</code>.</li>
<li>Data to pass to the handler. If no data is necessary, NULL should be
given.</li>
</ol>
<p>It is described in the <a
href="https://docs.gtk.org/gobject/func.signal_connect.html">GObject API
Reference</a>. Correctly, <code>g_signal_connect</code> is a macro (not
a C function).</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#define g_signal_connect </span><span class="op">(</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>  instance<span class="op">,</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  detailed_signal<span class="op">,</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>  c_handler<span class="op">,</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>  data</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a><span class="op">)</span></span></code></pre></div>
<p>You can find the description of each signal in the API reference
manual. For example, “activate” signal is in <a
href="https://docs.gtk.org/gio/signal.Application.activate.html">GApplication
section</a> in the GIO API Reference.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>activate <span class="op">(</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>  GApplication<span class="op">*</span> self<span class="op">,</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>  gpointer user_data</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a><span class="op">)</span></span></code></pre></div>
<p>This is a declaration of the “activate” signal handler. You can use
any name instead of “activate” in the declaration above. The parameters
are:</p>
<ul>
<li>self is an instance to which the signal belongs.</li>
<li>user_data is a data defined in the fourth argument of the
<code>g_signal_connect</code> function. If it is NULL, then you can
ignore and leave out the second parameter.</li>
</ul>
<p>API reference manual is very important. You should see and understand
it.</p>
<p>Let’s compile the source file above (<code>pr2.c</code>) and run
it.</p>
<pre><code>$ gcc `pkg-config --cflags gtk4` pr2.c `pkg-config --libs gtk4`
$ ./a.out
GtkApplication is activated.
$</code></pre>
<p>OK, well done. However, you may have noticed that it’s painful to
type such a long line to compile. It is a good idea to use shell script
to solve this problem. Make a text file which contains the following
line.</p>
<pre><code>gcc `pkg-config --cflags gtk4` $1.c `pkg-config --libs gtk4`</code></pre>
<p>Then, save it under the directory $HOME/bin, which is usually
/home/(username)/bin. (If your user name is James, then the directory is
/home/james/bin). And turn on the execute bit of the file. If the
filename is <code>comp</code>, do like this:</p>
<pre><code>$ chmod 755 $HOME/bin/comp
$ ls -log $HOME/bin
    ...  ...  ...
-rwxr-xr-x 1   62 May 23 08:21 comp
    ...  ...  ...</code></pre>
<p>If this is the first time that you make a $HOME/bin directory and
save a file in it, then you need to logout and login again.</p>
<pre><code>$ comp pr2
$ ./a.out
GtkApplication is activated.
$</code></pre>
<h2 id="gtkwindow-and-gtkapplicationwindow">GtkWindow and
GtkApplicationWindow</h2>
<h3 id="gtkwindow">GtkWindow</h3>
<p>A message “GtkApplication is activated.” was printed out in the
previous subsection. It was good in terms of a test of GtkApplication.
However, it is insufficient because Gtk is a framework for graphical
user interface (GUI). Now we go ahead with adding a window into this
program. What we need to do is:</p>
<ol type="1">
<li>Create a GtkWindow.</li>
<li>Connect it to GtkApplication.</li>
<li>Show the window.</li>
</ol>
<p>Now rewrite the function <code>app_activate</code>.</p>
<h4 id="create-a-gtkwindow">Create a GtkWindow</h4>
<p>@@<span class="citation" data-cites="include">@include</span>
misc/pr3.c app_activate @@@</p>
<p>Widget is an abstract concept that includes all the GUI interfaces
such as windows, dialogs, buttons, multi-line text, containers and so
on. And GtkWidget is a base object from which all the GUI objects
derive.</p>
<pre><code>parent &lt;-----&gt; child
GtkWidget -- GtkWindow</code></pre>
<p>GtkWindow includes GtkWidget at the top of its object.</p>
<figure>
<img src="image/window_widget.png" alt="GtkWindow and GtkWidget" />
<figcaption aria-hidden="true">GtkWindow and GtkWidget</figcaption>
</figure>
<p>The function <code>gtk_window_new</code> is defined as follows.</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>GtkWidget <span class="op">*</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>gtk_window_new <span class="op">(</span><span class="dt">void</span><span class="op">);</span></span></code></pre></div>
<p>By this definition, it returns a pointer to GtkWidget, not GtkWindow.
It actually creates a new GtkWindow instance (not GtkWidget) but returns
a pointer to GtkWidget. However,the pointer points the GtkWidget and at
the same time it also points GtkWindow that contains GtkWidget in
it.</p>
<p>If you want to use <code>win</code> as a pointer to a GtkWindow type
instance, you need to cast it.</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="op">(</span>GtkWindow <span class="op">*)</span> win</span></code></pre></div>
<p>It works, but isn’t usually used. Instead, <code>GTK_WINDOW</code>
macro is used.</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a>GTK_WINDOW <span class="op">(</span>win<span class="op">)</span></span></code></pre></div>
<p>The macro is recommended because it does not only cast the pointer
but it also checks the type.</p>
<h4 id="connect-it-to-gtkapplication.">Connect it to
GtkApplication.</h4>
<p>The function <code>gtk_window_set_application</code> is used to
connect GtkWindow to GtkApplication.</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>gtk_window_set_application <span class="op">(</span>GTK_WINDOW <span class="op">(</span>win<span class="op">),</span> GTK_APPLICATION <span class="op">(</span>app<span class="op">));</span></span></code></pre></div>
<p>You need to cast <code>win</code> to GtkWindow and <code>app</code>
to GtkApplication with <code>GTK_WINDOW</code> and
<code>GTK_APPLICATION</code> macro.</p>
<p>GtkApplication continues to run until the related window is
destroyed. If you didn’t connect GtkWindow and GtkApplication,
GtkApplication destroys itself immediately. Because no window is
connected to GtkApplication, GtkApplication doesn’t need to wait
anything. As it destroys itself, the GtkWindow is also destroyed.</p>
<h4 id="show-the-window.">Show the window.</h4>
<p>The function <code>gtk_window_present</code> presents the window to a
user (shows it to the user).</p>
<p>GTK 4 changes the default widget visibility to on, so every widget
doesn’t need to change it to on. But, there’s an exception. Top level
window (this term will be explained later) isn’t visible when it is
created. So you need to use the function above to show the window.</p>
<p>You can use <code>gtk_widget_set_visible (win, true)</code> instead
of <code>gtk_window_present</code>. But the behavior of these two is
different. Suppose there are two windows win1 and win2 on the screen and
win1 is behind win2. Both windows are visible. The function
<code>gtk_widget_set_visible (win1, true)</code> does nothing because
win1 is already visible. So, win1 is still behind win2. The other
function <code>gtk_window_present (win1)</code> moves win1 to the top of
the stack of the windows. Therefore, if you want to present the window,
you should use <code>gtk_window_present</code>.</p>
<p>Two functions <code>gtk_widget_show</code> and
<code>gtk_widget_hide</code> is deprecated since GTK 4.10. You should
use <code>gtk_widget_set_visible</code> instead.</p>
<p>Save the program as <code>pr3.c</code>, then compile and run it.</p>
<pre><code>$ comp pr3
$ ./a.out</code></pre>
<p>A small window appears.</p>
<figure>
<img src="image/screenshot_pr3.png" alt="Screenshot of the window" />
<figcaption aria-hidden="true">Screenshot of the window</figcaption>
</figure>
<p>Click on the close button then the window disappears and the program
finishes.</p>
<h3 id="gtkapplicationwindow">GtkApplicationWindow</h3>
<p>GtkApplicationWindow is a child object of GtkWindow. It has some
extra feature for better integration with GtkApplication. It is
recommended to use it as the top-level window of the application instead
of GtkWindow.</p>
<p>Now rewrite the program and use GtkApplicationWindow.</p>
<p>@@<span class="citation" data-cites="include">@include</span>
misc/pr4.c app_activate @@@</p>
<p>When you create GtkApplicationWindow, you need to give GtkApplication
instance as an argument. Then it automatically connect these two
instances. So you don’t need to call
<code>gtk_window_set_application</code> any more.</p>
<p>The program sets the title and the default size of the window.
Compile it and run <code>a.out</code>, then you will see a bigger window
with its title “pr4”.</p>
<figure>
<img src="image/screenshot_pr4.png" alt="Screenshot of the window" />
<figcaption aria-hidden="true">Screenshot of the window</figcaption>
</figure>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
  </body>
  </html>
